home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / finger / part03 < prev    next >
Encoding:
Text File  |  1992-04-04  |  61.9 KB  |  2,306 lines

  1. Newsgroups: comp.sources.unix
  2. From: phil@Shiva.COM (Phil Budne)
  3. Subject: v25i166: finger - Phil's Finger Program, Part03/07
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: phil@Shiva.COM (Phil Budne)
  8. Posting-Number: Volume 25, Issue 166
  9. Archive-Name: finger/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 7)."
  18. # Contents:  Install.cpp MANIFEST comdef.c doremote.c finger.1 getent.c
  19. #   mcheck.c read_vmunix.c ttylocfile.c undomain.c
  20. # Wrapped by budd@bu-it on Fri Jul  6 13:22:01 1990
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f Install.cpp -a "${1}" != "-c" ; then 
  23.   echo shar: Will not over-write existing file \"Install.cpp\"
  24. else
  25. echo shar: Extracting \"Install.cpp\" \(4755 characters\)
  26. sed "s/^X//" >Install.cpp <<'END_OF_Install.cpp'
  27. X/*
  28. X * Copyright (C) 1988, 1990  Philip L. Budne
  29. X *
  30. X * This file is part of "Phil's Finger Program".
  31. X *
  32. X * This program is free software; you can redistribute it and/or modify
  33. X * it under the terms of the GNU General Public License as published by
  34. X * the Free Software Foundation; either version 1, or (at your option)
  35. X * any later version.
  36. X */
  37. X
  38. X/*
  39. X * $Id: Install.cpp,v 3.0 90/07/06 13:09:49 budd Rel $
  40. X */
  41. X
  42. X# include "local.h"
  43. X
  44. X# ifdef USG
  45. XCHOWN=/bin/chown
  46. X# else  /* USG not defined */
  47. XCHOWN=/etc/chown
  48. X# endif /* USG not defined */
  49. X
  50. X/* ttyloc program runs setuid */
  51. XTTYLOCOWN=daemon
  52. X
  53. X/*fingerd must have this path built in (see FINGERPATHS in fingerd.c/local.h)*/
  54. XDEST=/usr/local/bin
  55. X
  56. X/* you might change this to '1' if you don't have/use manl (local) */
  57. XMANSEC='l'
  58. X/* base for man files */
  59. XMAND=/usr/man
  60. X
  61. X/* saved nlist file (finger needs to be in kmem group under 4.3) */
  62. X# ifdef KMEM_GROUP
  63. XNLISTGRP=KMEM_GROUP
  64. X# else  /* KMEM_GROUP not defined */
  65. XNLISTGRP=daemon
  66. X# endif /* KMEM_GROUP not defined */
  67. X
  68. X# ifdef SAVED_NLIST
  69. XNFILE=SAVED_NLIST
  70. X# else  /* SAVED_NLIST not defined */
  71. XNFILE=/etc/finger-saved-nlist
  72. X# endif /* SAVED_NLIST not defined */
  73. X
  74. X# ifdef NLIST_MODE
  75. XNFILEMODE=NLIST_MODE
  76. X# else  /* NLIST_MODE not defined */
  77. XNFILEMODE=664
  78. X# endif /* NLIST_MODE not defined */
  79. X
  80. X# ifdef sun
  81. XFINGERDDEST=/usr/etc/in.fingerd
  82. XFINGERDSOURCE=in.fingerd
  83. X# if SunOS < 400
  84. XINETDCONF=/etc/servers
  85. X# else  /* not SunOS < 400 */
  86. XINETDCONF=/etc/inetd.conf
  87. X# endif /* not SunOS < 400 */
  88. X# else  /* sun not defined */
  89. X# ifdef sgi
  90. XFINGERDDEST=/usr/etc/fingerd
  91. XFINGERDSOURCE=fingerd
  92. XINETDCONF=/usr/etc/inetd.conf
  93. X# else  /* sgi not defined */
  94. XFINGERDDEST=/etc/fingerd
  95. XFINGERDSOURCE=fingerd
  96. X# ifdef INETD
  97. XINETDCONF=/etc/inetd.conf
  98. X# endif /* INETD defined */
  99. X# endif /* sgi not defined */
  100. X# endif /* sun not defined */
  101. X
  102. X# ifdef sgi
  103. X/* what about other USG systems? */
  104. XUCBDIR=/usr/bsd
  105. X# else  /* sgi not defined */
  106. XUCBDIR=/usr/ucb
  107. X# endif /* sgi not defined */
  108. X
  109. Xecho binary dir is $DEST finger setgid $NLISTGRP
  110. Xecho manual pages to $MAND section $MANSEC
  111. Xecho saved namelist is $NFILE group $NLISTGRP mode $NFILEMODE
  112. Xecho ttyloc dir is TTYLOC_DIR owner $TTYLOCOWN files mode TTYLOC_MODE
  113. Xecho $FINGERDSOURCE to $FINGERDDEST
  114. Xecho ''
  115. Xecho "Type RETURN to continue"
  116. Xread FOOBAR
  117. X
  118. X/* flush groty versions */
  119. Xif [ -r $UCBDIR/finger ]; then
  120. X    echo moving $UCBDIR/finger to $UCBDIR/ofinger
  121. X    mv $UCBDIR/finger $UCBDIR/ofinger
  122. Xfi
  123. Xif [ -r $UCBDIR/f ]; then
  124. X    echo moving $UCBDIR/f to $UCBDIR/of
  125. X    mv $UCBDIR/f $UCBDIR/of
  126. Xfi
  127. Xif [ -r $UCBDIR/whois ]; then
  128. X    echo moving $UCBDIR/whois to $UCBDIR/nicname
  129. X    mv $UCBDIR/whois $UCBDIR/nicname
  130. Xfi
  131. X
  132. Xecho ''
  133. Xecho installing $DEST/finger setgid $NLISTGRP
  134. Xcp xf $DEST/finger
  135. X# ifndef NOSTRIP
  136. Xstrip $DEST/finger
  137. X# endif /* NOSTRIP not defined */
  138. Xchgrp $NLISTGRP $DEST/finger
  139. Xchmod 2711 $DEST/finger
  140. Xls -lg $DEST/finger
  141. X
  142. Xfor x in whois whoj f; do
  143. X    if [ ! -r $DEST/$x ]; then
  144. X        echo linking $DEST/$x to $DEST/finger
  145. X        (cd $DEST; ln -s finger $x)
  146. X    fi
  147. X    ls -l $DEST/$x
  148. Xdone
  149. X
  150. Xecho ''
  151. Xif [ ! -r $NFILE ]; then
  152. X    echo creating empty $NFILE
  153. X    touch $NFILE
  154. Xfi
  155. Xchgrp $NLISTGRP $NFILE
  156. Xchmod $NFILEMODE $NFILE
  157. Xls -lg $NFILE
  158. X
  159. Xecho ''
  160. Xecho installing $FINGERDSOURCE as $FINGERDDEST
  161. Xcp $FINGERDSOURCE $FINGERDDEST
  162. X# ifndef NOSTRIP
  163. Xstrip $FINGERDDEST
  164. X# endif /* NOSTRIP not defined */
  165. X# ifdef INETD
  166. Xecho "Checking $INETDCONF"
  167. Xif grep finger $INETDCONF; then
  168. X    true;
  169. Xelse
  170. X    echo "Perhaps you should to edit $INETDCONF"
  171. Xfi
  172. X# else  /* INETD not defined */
  173. Xecho "Checking /etc/rc files"
  174. Xif grep /etc/fingerd /etc/rc*; then
  175. X    true;
  176. Xelse
  177. X    echo "You might want to start fingerd from /etc/rc.local"
  178. Xfi
  179. X# endif /* INETD not defined */
  180. X
  181. Xecho ''
  182. Xecho installing $DEST/ttyloc setuid $TTYLOCOWN
  183. Xcp ttyloc $DEST
  184. X# ifndef NOSTRIP
  185. Xstrip $DEST/ttyloc
  186. X# endif /* NOSTRIP not defined */
  187. X$CHOWN $TTYLOCOWN $DEST/ttyloc
  188. Xchmod 4711 $DEST/ttyloc
  189. Xls -lg $DEST/ttyloc
  190. X
  191. Xecho ''
  192. Xecho installing $DEST/ttyask
  193. Xcp ttyask $DEST
  194. X# ifndef NOSTRIP
  195. Xstrip $DEST/ttyask
  196. X# endif /* NOSTRIP not defined */
  197. X(
  198. X    cd $DEST
  199. X    ls -lg ttyask
  200. X    for x in ttyplace ttyroom ttyrandom ttycycle; do
  201. X    rm -f $x
  202. X    echo linking $x to ttyask
  203. X    ln -s ttyask $x
  204. X    ls -l $x
  205. X    done
  206. X)
  207. X
  208. X# ifdef TTYLOC_DIR
  209. Xecho ''
  210. Xif [ ! -d TTYLOC_DIR ]; then
  211. X    echo creating TTYLOC_DIR
  212. X    mkdir TTYLOC_DIR
  213. Xfi
  214. X$CHOWN $TTYLOCOWN TTYLOC_DIR
  215. Xls -lgd TTYLOC_DIR
  216. X# else  /* TTYLOC_DIR not defined */
  217. Xecho 'TTYLOC_DIR not defined in local.h!!' 1>&2
  218. X# endif /* TTYLOC_DIR not defined */
  219. X
  220. X# ifdef USG
  221. Xecho ''
  222. Xecho installing man uptime in $UCBDIR/uptime
  223. Xcp uptime $UDBDIR/uptime
  224. X# endif /* USG defined */
  225. X
  226. Xecho ''
  227. Xecho installing man pages
  228. Xcp finger.1    $MAND/man$MANSEC/finger.$MANSEC
  229. Xcp ttyloc.1    $MAND/man$MANSEC/ttyloc.$MANSEC
  230. Xcp nttyloc.5    $MAND/man5
  231. Xcp finger.conf.5 $MAND/man5
  232. Xcp fingerd.8c    $MAND/man8
  233. X
  234. Xecho ''
  235. Xecho 'taking it out for a spin!'
  236. X$DEST/finger
  237. END_OF_Install.cpp
  238. if test 4755 -ne `wc -c <Install.cpp`; then
  239.     echo shar: \"Install.cpp\" unpacked with wrong size!
  240. fi
  241. # end of overwriting check
  242. fi
  243. if test -f MANIFEST -a "${1}" != "-c" ; then 
  244.   echo shar: Will not over-write existing file \"MANIFEST\"
  245. else
  246. echo shar: Extracting \"MANIFEST\" \(6086 characters\)
  247. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  248. X   File Name        Archive #    Description
  249. X-----------------------------------------------------------
  250. X COMDEFALL                 1    Run all files thru comdef
  251. X COPYING                   6    Copying conditions (GNU General Public Licence)
  252. X COPYRIGHT                 1    Copyright as it appears in C files
  253. X COUNT                     1    Shell script to count TODO and WISHES
  254. X Cover                     1    Cover letter
  255. X DIFFALL                   1    Run diff for all .orig files (see ORIG)
  256. X Distfile                  1    Distfile for local testing
  257. X FINDDEFS                  1    Shell script to local defined symbols
  258. X History.h                 7    Revision history, version number
  259. X Install.cpp               3    Cpp input for installation shell script
  260. X MANIFEST                  3    This file
  261. X MODES                     1    Emacs Local modes for bottom of new files
  262. X Makefile                  2    Master Makefile
  263. X ORIG                      1    Shell script to save files before edit
  264. X README                    1    Documentation
  265. X SAMPLE-conf               1    Sample finger.conf file
  266. X SAMPLE-flags              1    Sample local-flags file
  267. X SAMPLE-local.h            2    Sample local.h file
  268. X SAMPLE-nttyloc            1    Sample /etc/nttyloc file
  269. X TODO                      2    Things that "should" be done
  270. X VERSION                   1    Version of this KIT
  271. X WISHES                    1    Things that "could" be done
  272. X args.c                    5    Argument processor. main is here.
  273. X args.h                    2    Argument definitions
  274. X autoconfig                5    Creates local.h from thin air
  275. X cc-M                      1    Cheap substitute for cc's without -M flag
  276. X checkmode.c               2    Check file modes for autoconfig
  277. X comdef.c                  3    Automagic utility to comment #else and #endifs
  278. X conf.c                    4    Read finger.conf file
  279. X daemon.c                  2    list of interesting daemon parent names/titles
  280. X daemon.h                  1    struct daemon for daemon.c
  281. X defs.awk                  1    Awk program for FINDDEFS
  282. X doremote.c                3    Connect to remote fingerds with TCP
  283. X finger.1                  3    Finger Man page
  284. X finger.c                  6    Output formatting. main is in args.c
  285. X finger.conf.5             2    Manual page for finger.conf file
  286. X finger.h                  2    General definitions for all programs
  287. X fingerd.8c                1    Manual page for finger daemon
  288. X fingerd.c                 6    Finger daemon (for inetd or stand alone use)
  289. X getcommand.c              6    Much terrible wizardry here
  290. X getent.c                  3    Scan utmp entries to create LUSERs
  291. X getgroup.c                1    Report file GID for autoconfig script
  292. X getperson.c               5    Create PERSONal information structs
  293. X getttyloc.c               7    Cons up console location
  294. X getttytype.c              2    Get ttytype (/etc/ttytype or via getttyent())
  295. X getut.c                   2    Logic to read /etc/utmp file
  296. X global.c                  1    Global variables
  297. X hungry                    1    Directory for hungry stuff
  298. X hungry/README             1    hungry README
  299. X hungry/hungry.1c          1    hungry man page
  300. X hungry/hungry.c           1    hungry program
  301. X hungry/hungry.h           1    hungry defns
  302. X hungry/rwho-changes       1    changes for rwho
  303. X hungry/rwho.1c-changes    1    changes for rwho man page
  304. X hungry/rwhod-changes      1    changes for rwhod
  305. X inet_netof.c              1    
  306. X inet_ntoa.c               1    
  307. X info.h                    1    Structure of saved namelist file
  308. X inquire.c                 1    Logic to read inquire database(s) for person.c
  309. X inquire.h                 1    More inquire help.
  310. X kmem.c                    2    Routines to open and read mem, kmem, swap
  311. X kmem.h                    1    Defns for kmem.c usage.
  312. X lastlog.c                 2    Read /usr/adm/lastloc (ACK)
  313. X locname.c                 1    Cons up name for ttyloc files (for set/read)
  314. X luser.h                   2    Basic LUSER check
  315. X make-version              1    Create version.c using pversion
  316. X mcheck.c                  3    Check for (new) mail
  317. X myecho.c                  1    Avoid escape expansion by S5 echo commands
  318. X mywhoami.c                1    whoami command for autoconfig
  319. X names.c                   4    Read /vmunix and much more!!
  320. X newmanifest.c             2    Crock to merge MANIFEST and arg list
  321. X nttyloc.5                 2    Man file for nttyloc file
  322. X output.c                  4    Output related routines
  323. X output.h                  1    Output file defn and max line length
  324. X person.h                  1    Per Person information
  325. X pr.h                      1    Per Process information
  326. X pversion.c                1    Print version number using History.h
  327. X read_vmunix.c             3    Just plain awful stuff here.
  328. X readpr.c                  5    Read process table from kernel (ACK!)
  329. X remote.h                  1    Structs for collecting remote objects to finger
  330. X select.c                  4    The envelope please
  331. X skip.c                    1    skip (non)spaces
  332. X string.c                  2    Common string routines
  333. X strings.h                 1    strings.h helper for USG systems
  334. X switch.c                  4    Switch (option) processing
  335. X switch.h                  2    Switch (option) definitions
  336. X symdate.c                 1    Used to create symdate.h from syms.h
  337. X syms.h                    2    Symbols to read from kernel
  338. X tsel.h                    1    Pick a terminal, any terminal
  339. X ttyask.c                  5    Front end for ttyloc
  340. X ttyloc.1                  2    Man page for ttyloc
  341. X ttyloc.c                  2    Set user terminal location
  342. X ttylocfile.c              3    read (n)ttyloc file
  343. X ttylocfile.h              1    defns for ttylocfile.c
  344. X undomain.c                3    Strip domains and prefixes from hosts
  345. X upper.c                   1    Uppercasification table
  346. X upper.h                   1    Uppercasification table extern
  347. X uptime.c                  2    /usr/ucb/uptime for USG systems
  348. X ustruct.c                 5    Awful system dependant code
  349. X ustruct.h                 2    Common defines for users of u/proc structs
  350. X waitstate.h               1    Translations of kernel sleeps
  351. X whois.c                   4    Output formatting big time
  352. X whoj.c                    2    Quickie output formatting
  353. X ymakefile                 4    Real makefile.
  354. END_OF_MANIFEST
  355. if test 6086 -ne `wc -c <MANIFEST`; then
  356.     echo shar: \"MANIFEST\" unpacked with wrong size!
  357. fi
  358. # end of overwriting check
  359. fi
  360. if test -f comdef.c -a "${1}" != "-c" ; then 
  361.   echo shar: Will not over-write existing file \"comdef.c\"
  362. else
  363. echo shar: Extracting \"comdef.c\" \(5921 characters\)
  364. sed "s/^X//" >comdef.c <<'END_OF_comdef.c'
  365. X/*
  366. X * comdef.c -- comment defines automagicly
  367. X *    esp for nasty ANSI conforming CPPs!
  368. X *
  369. X * Copyright (C) 1986, 1990  Philip L. Budne
  370. X *
  371. X * This file is part of "Phil's Finger Program".
  372. X *
  373. X * This program is free software; you can redistribute it and/or modify
  374. X * it under the terms of the GNU General Public License as published by
  375. X * the Free Software Foundation; either version 1, or (at your option)
  376. X * any later version.
  377. X *
  378. X */
  379. X
  380. X# ifndef lint
  381. Xstatic char *rcsid = "$Id: comdef.c,v 3.0 90/07/06 13:10:26 budd Rel $";
  382. X# endif /* lint not defined */
  383. X
  384. X# include <stdio.h>
  385. X# include <ctype.h>
  386. X
  387. X/* Should all be runtime options: */
  388. X# define USEDEF                /* check for if(n)def for comments */
  389. X/*# define DEBUG            /* output debug info */
  390. X
  391. X/*
  392. X * the following 4 (PRESERVE_xxx) output "#[s\t]thing" as input if
  393. X * defined.  Otherwise if INDENTATION is defined they will be indented
  394. X * according to depth.  If INDENT_OTHER is defined even includes and
  395. X * defines will be indented (otherwise indented to MIN_INDENT).  if
  396. X * IDENTATION is not defined all output will be indented to
  397. X * MIN_INDENT.
  398. X */
  399. X
  400. X/*# define PRESERVE_BAD            /* preserve indentation on failures */
  401. X/*# define PRESERVE_IF            /* preserve indentation on ifs */
  402. X/*# define PRESERVE_ENDIF        /* preserve indentation on endifs */
  403. X/*# define PRESERVE_OTHER        /* preserve indentation on define... */
  404. X/*# define INDENTATION            /* indent by depth (but not define..)*/
  405. X/*# define INDENT_OTHER            /* indent define/include.. by depth */
  406. X
  407. X# ifndef MIN_INDENT
  408. X# define MIN_INDENT 1
  409. X# endif /* MIN_INDENT not defined */
  410. X
  411. X# define REL(i) ((i)+MIN_INDENT)
  412. X
  413. X# define EOS '\0'
  414. X
  415. X# define MAX 100            /* plenty!! */
  416. Xchar stack[MAX][ 256 ];
  417. Xint flags[MAX];
  418. Xint sp = -1;
  419. X
  420. X# define FL_NOT 01            /* inverse of "condition" */
  421. X# define FL_ELS 02            /* seen else */
  422. X# define FL_DEF 04            /* was ifdef or ifndef */
  423. X
  424. Xmain() {
  425. X    char line[ 1024 ], saved[ 1024 ];
  426. X    register char *cp, *xp, *yp;
  427. X    int ln;
  428. X
  429. X    ln = -1;
  430. X    while( gets( line ) ) {
  431. X    cp = line;
  432. X    ln++;
  433. X
  434. X    while( *cp && isspace( *cp ) )
  435. X        cp++;
  436. X
  437. X    if( *cp != '#' ) {
  438. X        puts( line );
  439. X        continue;
  440. X    }
  441. X    cp++;
  442. X
  443. X    while( *cp && isspace( *cp ) )
  444. X        cp++;
  445. X
  446. X    xp = cp;
  447. X    while( isalpha( *cp ) )
  448. X        cp++;
  449. X
  450. X    strcpy( saved, line );        /* sigh */
  451. X    if( *cp != EOS ) {
  452. X        if( !isspace( *cp ) ) {
  453. X        fprintf( stderr, "%d: bad line: %s\n", ln, line );
  454. X        puts( line );
  455. X        continue;
  456. X        }
  457. X        *cp++ = EOS;
  458. X        while( isspace( *cp ) )
  459. X        cp++;
  460. X    }
  461. X
  462. X# ifdef DEBUG
  463. X    fprintf( stderr, " <<< %s >>>\n", xp );
  464. X# endif /* DEBUG defined */
  465. X    if( strncmp( xp, "if", 2 ) == 0 || strcmp( xp, "elif" ) == 0 ) {
  466. X        if( strcmp( xp, "elif" ) != 0 )
  467. X        sp++;
  468. X# ifdef PRESERVE_IF
  469. X        puts( saved );
  470. X# else  /* PRESERVE_IF not defined */
  471. X        putit( REL(sp), xp );
  472. X        putchar(' ');
  473. X        puts( cp );
  474. X# endif /* PRESERVE_IF not defined */
  475. X
  476. X        if( sp == MAX )
  477. X        fprintf( stderr, "%d: Beyond MAX", ln );
  478. X        else {
  479. X        yp = cp;
  480. X        while( *cp != EOS )
  481. X            if( *cp == '/' && cp[1] == '*' ) {
  482. X            while( isspace( cp[-1] ) && cp >= yp )
  483. X                cp--;
  484. X            *cp = EOS;
  485. X            break;
  486. X            }
  487. X            else
  488. X            cp++;
  489. X# ifdef DEBUG
  490. X        fprintf( stderr, "saving: %s\n", yp );
  491. X# endif /* DEBUG defined */
  492. X        strcpy( stack[sp], yp );
  493. X        flags[sp] = 0;
  494. X
  495. X        /* check for !exp ???!! */
  496. X        if( strcmp( xp, "ifndef" ) == 0 ) {
  497. X            flags[sp] |= FL_NOT;
  498. X# ifdef USEDEF
  499. X            flags[sp] |= FL_DEF;
  500. X# endif /* USEDEF defined */
  501. X        }
  502. X# ifdef USEDEF
  503. X        else if( strcmp( xp, "ifdef" ) == 0 )
  504. X            flags[sp] |= FL_DEF;
  505. X# endif /* USEDEF defined */
  506. X        }
  507. X    }
  508. X    else if( strcmp( xp, "else" ) == 0 ) {
  509. X        if( sp < 0 ) {
  510. X        fprintf( stderr, "%d: else not under if\n", ln );
  511. X# ifdef PRESERVE_BAD
  512. X        puts( saved );
  513. X# else  /* PRESERVE_BAD not defined */
  514. X        putit( REL(sp), "else" );
  515. X        putchar('\n');
  516. X# endif /* PRESERVE_BAD not defined */
  517. X        }
  518. X        else {
  519. X        flags[sp] ^= FL_NOT;    /* invert not-ness */
  520. X        if( flags[sp] & FL_ELS )
  521. X            fprintf( stderr, "double else for %s at line %d????\n",
  522. X                stack[ sp ], ln );
  523. X# ifdef PRESERVE_BAD
  524. X        fputs( line, stdout );
  525. X# else  /* PRESERVE_BAD not defined */
  526. X        putit( REL(sp), "else" );
  527. X# endif /* PRESERVE_BAD not defined */
  528. X        /* extra space to match indent on endif */
  529. X        putchar( ' ' );
  530. X        comment(sp);
  531. X        }
  532. X    }
  533. X    else if( strcmp( xp, "endif" ) == 0 ) {
  534. X        if( sp >= MAX || sp < 0 ) {
  535. X        if( sp < 0 )
  536. X            fprintf( stderr, "%d: Too many endifs\n", ln );
  537. X# ifdef PRESERVE_BAD
  538. X        puts( saved );
  539. X# else  /* PRESERVE_BAD not defined */
  540. X        putit( REL(sp), "endif");
  541. X        putchar('\n');
  542. X# endif /* PRESERVE_BAD not defined */
  543. X        } /* bad sp */
  544. X        else {
  545. X# ifdef PRESERVE_ENDIF
  546. X        fputs( line, stdout );
  547. X# else  /* PRESERVE_ENDIF not defined */
  548. X        putit( REL(sp), "endif" );
  549. X# endif /* PRESERVE_ENDIF not defined */
  550. X        comment(sp+1);        /* decr in wrong place for indenting */
  551. X        } /* ok sp */
  552. X        sp--;
  553. X    } /* found endif */
  554. X    else {                /* found something else */
  555. X# ifdef PRESERVE_OTHER
  556. X        puts( saved );        /* define, include, or something... */
  557. X# else  /* PRESERVE_OTHER not defined */
  558. X# ifdef INDENT_OTHER
  559. X        putit( REL(sp+1), xp );
  560. X# else  /* INDENT_OTHER not defined */
  561. X        putit( MIN_INDENT, xp );
  562. X# endif /* INDENT_OTHER not defined */
  563. X        putchar(' ');
  564. X        puts( cp );
  565. X# endif /* PRESERVE_OTHER not defined */
  566. X    } /* define, include ... */
  567. X    } /* while */
  568. X} /* main */
  569. X
  570. Xputit( off, s )
  571. X    register off;
  572. X    char *s;
  573. X{
  574. X# ifdef DEBUG
  575. X    fprintf( stderr, "level %d off %d putit: %s\n", sp, off, s );
  576. X# endif /* DEBUG defined */
  577. X
  578. X    putchar('#');
  579. X
  580. X# ifdef INDENTATION
  581. X    if( off < MIN_INDENT )
  582. X# endif /* INDENTATION defined */
  583. X    off = MIN_INDENT;
  584. X
  585. X    while( off-- > 0 )
  586. X    putchar(' ');
  587. X
  588. X    fputs( s, stdout );
  589. X}
  590. X
  591. Xcomment() {                /* comment elses and endif */
  592. X    fputs(" /* ", stdout );
  593. X    if( (flags[sp] & FL_DEF) == 0 && (flags[sp] & FL_NOT) )
  594. X    fputs("not ", stdout );
  595. X
  596. X    fputs( stack[sp], stdout );
  597. X    if( flags[sp] & FL_DEF )
  598. X    if( flags[sp] & FL_NOT )
  599. X        fputs(" not defined", stdout );
  600. X    else
  601. X        fputs(" defined", stdout );
  602. X    puts( " */" );
  603. X} /* comment */
  604. END_OF_comdef.c
  605. if test 5921 -ne `wc -c <comdef.c`; then
  606.     echo shar: \"comdef.c\" unpacked with wrong size!
  607. fi
  608. # end of overwriting check
  609. fi
  610. if test -f doremote.c -a "${1}" != "-c" ; then 
  611.   echo shar: Will not over-write existing file \"doremote.c\"
  612. else
  613. echo shar: Extracting \"doremote.c\" \(5687 characters\)
  614. sed "s/^X//" >doremote.c <<'END_OF_doremote.c'
  615. X/*
  616. X * doremote.c -- contact remote hosts for finger
  617. X *
  618. X * Copyright (c) 1986, 1990  Barry Z. Shein and Philip L. Budne
  619. X *
  620. X * This file is part of "Phil's Finger Program".
  621. X *
  622. X * This program is free software; you can redistribute it and/or modify
  623. X * it under the terms of the GNU General Public License as published by
  624. X * the Free Software Foundation; either version 1, or (at your option)
  625. X * any later version.
  626. X */
  627. X
  628. X/*
  629. X *    Barry Shein, Boston University
  630. X *        routine to attach to remote finger server
  631. X *        addition to finger.c
  632. X *
  633. X *    Adapted to new finger; Phil Budne, Boston University
  634. X *
  635. X *    Conforms (as much as I can tell) to RFC742
  636. X *    [which is a pretty liberal document]
  637. X *
  638. X *    Note: Not all finger daemons support multiple requests.
  639. X *    According to my reading of the RFC this is allowed, the
  640. X *    correct format (which we use here) is name,name,name\r\n
  641. X */
  642. X
  643. X
  644. X# ifndef lint
  645. Xstatic char *rcsid = "$Id: doremote.c,v 3.0 90/07/06 13:10:32 budd Rel $";
  646. X# endif /* lint not defined */
  647. X
  648. X# include <sys/types.h>
  649. X# include <netinet/in.h>
  650. X# include <sys/socket.h>
  651. X# include <strings.h>
  652. X# include <netdb.h>
  653. X# include <ctype.h>
  654. X# include <stdio.h>
  655. X
  656. X# include "remote.h"
  657. X# include "args.h"
  658. X# include "finger.h"
  659. X
  660. X# define SERVICE "finger"
  661. X# define PROTOCOL "tcp"
  662. X
  663. Xextern char *inet_ntoa();        /* from library */
  664. X
  665. XFORWARD LOCAL void prhost();
  666. X
  667. X# ifndef DEF_PORT
  668. X# ifdef IPPORT_FINGER
  669. X# define DEF_PORT IPPORT_FINGER 
  670. X# else  /* IPPORT_FINGER not defined */
  671. X# define DEF_PORT 79
  672. X# endif /* IPPORT_FINGER not defined */
  673. X# endif /* DEF_PORT not defined */
  674. X
  675. XLOCAL short port;
  676. XGLOBAL void
  677. Xdoremote( hosts )
  678. XRHOST *hosts;
  679. X{
  680. X    register char *cp;
  681. X    struct servent *sp;
  682. X    struct hostent *hp;
  683. X    RUSER *rup;
  684. X
  685. X    if( hosts == NULL )
  686. X    return;
  687. X
  688. X    if((sp = getservbyname(SERVICE,PROTOCOL)) == NULL)
  689. X    port = htons( DEF_PORT );
  690. X    else
  691. X    port = sp->s_port;
  692. X
  693. X    /* loop for all host names */
  694. X    for( ; hosts != NULL ; hosts = hosts->rh_next ) {
  695. X
  696. X    cp = hosts->rh_name;            /* get host 'name' */
  697. X    rup = hosts->rh_user;            /* get pointer to user chain */
  698. X
  699. X    /* handle internet numeric format */
  700. X    if( isdigit( *cp ) ) {
  701. X        struct in_addr haddr;
  702. X        char temp[ 128 ];
  703. X
  704. X        haddr.s_addr = inet_addr( cp ); /* get address */
  705. X
  706. X        /* try to get name for address */
  707. X        if((hp = gethostbyaddr(&haddr, sizeof(haddr), AF_INET)) == NULL ) {
  708. X        if( net_host( temp, haddr ) )    /* failed, try network name */
  709. X            prhost( temp );
  710. X        else                /* total lossage */
  711. X            prhost( inet_ntoa( haddr ) ); /* reformat!! */
  712. X                        /* ie; 10.4 -> 10.0.0.4 */
  713. X        tryaddr( &haddr, rup );        /* try just given addr */
  714. X        continue;            /* next host */
  715. X        }
  716. X# ifdef JUST_ADDR_GIVEN
  717. X        prhost( hp->h_name );        /* official name */
  718. X        tryaddr( &haddr, rup );
  719. X        continue;                /* next host */
  720. X# endif /* JUST_ADDR_GIVEN defined */
  721. X    } /* given number */
  722. X    else if( (hp = gethostbyname(cp)) == NULL ) {
  723. X        /* try other networks here?! */
  724. X
  725. X# ifdef HAVE_H_ERRNO
  726. X        extern int h_errno, h_nerr;
  727. X        extern char *h_errlist[];
  728. X
  729. X        if( h_errno > 0 && h_errno <= h_nerr )
  730. X        fprintf(stderr,"%%%s: %s\n", h_errlist[h_errno], cp );
  731. X        else
  732. X# endif /* HAVE_H_ERRNO defined */
  733. X        fprintf(stderr,"%%Unknown host: %s\n", cp );
  734. X        continue;                /* next host */
  735. X    } /* hostbyname failed */
  736. X
  737. X    prhost( hp->h_name );        /* show official name */
  738. X# ifdef h_addr
  739. X    if( hp->h_addr_list != NULL ) {
  740. X        struct in_addr **lp;
  741. X
  742. X        for( lp = (struct in_addr **)hp->h_addr_list; *lp != NULL; lp++ ) {
  743. X        /* Trying... used to be here */
  744. X        if( tryaddr( *lp, rup ) )
  745. X            break;
  746. X        } /* for each address */
  747. X    } /* have address list */
  748. X    else
  749. X        fprintf(stderr,"%%No addresses?\n"); /* should get h_errno set! */
  750. X# else  /* h_addr not defined */
  751. X    tryaddr( hp->h_addr, rup );
  752. X# endif /* h_addr not defined */
  753. X    } /* for each host */
  754. X} /* doremote*/
  755. X
  756. Xint
  757. Xtryaddr( addr, rup )
  758. X    struct in_addr *addr;
  759. X    register RUSER *rup;
  760. X{
  761. X    char buf[BUFSIZ+1], *cp;
  762. X    struct sockaddr_in sin;        /* so much for protcol independance */
  763. X    FILE *f;
  764. X    int s;
  765. X
  766. X    if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
  767. X    perror("socket");
  768. X    return( FALSE );
  769. X    } /* socket failed */
  770. X
  771. X    bzero( (char *) &sin, sizeof( sin ) );
  772. X    bcopy( (char *) addr, (char *) &sin.sin_addr, sizeof( sin.sin_addr ) );
  773. X    sin.sin_family = AF_INET;
  774. X    sin.sin_port = port;
  775. X
  776. X# ifndef DONT_SAY_TRYING
  777. X    /* show all non-local addrs? */
  778. X    /* only show if multi-homed */
  779. X    /* only show address on error w/ multi-homed host? */
  780. X    printf("Trying %s...\n", inet_ntoa(*addr) );
  781. X# endif /* DONT_SAY_TRYING not defined */
  782. X
  783. X    if( connect( s, (char *) &sin, sizeof( sin ) ) < 0 ) {
  784. X    perror("connect");
  785. X    close(s);
  786. X    return( FALSE );
  787. X    }
  788. X
  789. X    /*
  790. X     *    Build into one buffer for the host
  791. X     *    terminate with CR-LF
  792. X     */
  793. X
  794. X    buf[0] = EOS;
  795. X    if( sw_whois )
  796. X    strcat(buf," /w ");
  797. X
  798. X    while( rup != NULL ) {
  799. X    strcat(buf,rup->ru_name) ;
  800. X    if( (rup = rup->ru_next) != NULL )
  801. X        strcat(buf,",");
  802. X    } /* while rup */
  803. X
  804. X    strcat(buf,"\r\n") ;
  805. X    /*
  806. X     *    Send request
  807. X     */
  808. X    if( write(s, buf, strlen( buf ) ) < 0 ) {
  809. X    perror("write");
  810. X    close(s);
  811. X    return( FALSE );
  812. X    }
  813. X
  814. X    /*
  815. X     *    Read and display result
  816. X     */
  817. X    f = fdopen(s, "r");
  818. X    while( fgets(buf, BUFSIZ, f) != NULL ) {
  819. X    /* blast \r as well? */
  820. X    if( (cp = index( buf, '\n' )) != NULL )    /* strip newlines */
  821. X        *cp = EOS;
  822. X    outline( buf );                /* output as much as will fit */
  823. X    } /* while */
  824. X    fclose( f );
  825. X    return( TRUE );
  826. X} /* doremote */
  827. X
  828. XLOCAL void
  829. Xprhost( name )
  830. Xchar *name;
  831. X{
  832. X    char buf[255];
  833. X
  834. X    blankline();
  835. X    sprintf(buf, "[%s]", name);     /* format string */
  836. X    outline( HZUP(buf) );        /* output it (upper cased) */
  837. X    fflush( stdout );
  838. X} /* prhost */
  839. X
  840. X/*
  841. X * Local variables:
  842. X * comment-column: 40
  843. X * End:
  844. X */
  845. END_OF_doremote.c
  846. if test 5687 -ne `wc -c <doremote.c`; then
  847.     echo shar: \"doremote.c\" unpacked with wrong size!
  848. fi
  849. # end of overwriting check
  850. fi
  851. if test -f finger.1 -a "${1}" != "-c" ; then 
  852.   echo shar: Will not over-write existing file \"finger.1\"
  853. else
  854. echo shar: Extracting \"finger.1\" \(6690 characters\)
  855. sed "s/^X//" >finger.1 <<'END_OF_finger.1'
  856. X.\" -*-nroff-*-
  857. X.\" $Id: finger.1,v 3.0 90/07/06 13:10:33 budd Rel $
  858. X.\" Copyright (c) 1987, 1990  Philip L. Budne
  859. X.TH FINGER local "31 January 1990"
  860. X.UC 4
  861. X.SH NAME
  862. Xf, finger, whois, whoj \- who are you, and what are you doing on my system
  863. X.SH SYNOPSIS
  864. X.B finger
  865. X[
  866. X.I /switch -switch +tty . user name @host name@host
  867. X]
  868. X
  869. X.B whois
  870. X[
  871. X.I /switch -switch +tty . user name @host name@host
  872. X]
  873. X
  874. X.B whoj
  875. X
  876. X.SH DESCRIPTION
  877. X.I Finger
  878. Xoutput contains the following information: Username, full name,
  879. Xprogram, idle time, biff/hunger state, tty name, write
  880. Xpermission, and terminal location.  If program (current process)
  881. Xis running
  882. X.IR setuid (2)
  883. Xas the super user, a plus (+) will be appended to the program.  If it
  884. Xis
  885. X.IR setuid (2)
  886. Xto some other user an exclamation mark (!) will be appended.  Biff on
  887. Xis signified by a period before the tty name, hunger by a comma, both
  888. Xby a semi-colon.  No write permission (mesg n) is flagged by an
  889. Xasterisk after the tty name.  If a user who is not logged in is
  890. Xspecified the time and line (or host) of last login are displayed,
  891. Xalong with the user's plan and mail file status.
  892. X.PP
  893. X.I Whois
  894. Xis an alias for
  895. X.I finger -whois.
  896. XThis format is multi-line, and includes all the information described
  897. Xabove as well as the user's user id, group id, home directory, login
  898. Xshell and groups, any plan which the person has placed in the file
  899. X.I \&.plan
  900. Xin their home directory, and the project on which they are working
  901. Xfrom the file
  902. X.I \&.project
  903. Xalso in the home directory. If the local system has an
  904. X.I inquire
  905. Xdatabase more information will be displayed.
  906. X.PP
  907. X.I Whoj
  908. Xis an alias for
  909. X.I finger -whoj
  910. Xthat displays only the terminal (or host name), user name, and program.
  911. X.PP
  912. XThe arguments accepted by
  913. X.I finger
  914. Xcan be one of: a user name, a personal name (first or last) from the
  915. Xpassword file or inquire database, a switch (starting with - or /), a
  916. Xterminal specification (+tty0d and +0d both mean the user on
  917. X/dev/tty0d, +tty0 matches /dev/tty0*), a period (specifies the user on
  918. Xthe stdin terminal) or a remote specification user@host. If no user is
  919. Xspecified
  920. X.I (finger @host)
  921. Xthen everyone is displayed.  You can also use
  922. X.I finger user@host@host
  923. Xto accomplish a primitive routing.  The only option passed to remote
  924. Xsystems is
  925. X.B /w
  926. Xas per RFC782.  However a backslash (two are needed to get past the
  927. Xshell) can be used to prevent local interpretation of a flag
  928. X.I "finger \e\e-w"
  929. Xfingers the user
  930. X.IR -w !
  931. Xand
  932. X.I "finger \e\e-v@bu-it.bu.edu"
  933. Xfinds what version of finger bu-it.bu.edu is running.
  934. X.PP
  935. X.I Finger
  936. Xand
  937. X.I whois
  938. Xoptions include:
  939. X.PP
  940. X.TP 15
  941. X.B /age
  942. XReplace idle time with user connect time.
  943. X.TP 15
  944. X.B /berkeley
  945. Ximitate BSD
  946. X.I finger
  947. X(usernames imply
  948. X.BR /whois/plan )
  949. X.TP 15
  950. X.B /follow
  951. Xfollow
  952. X.I \.forward
  953. Xfiles onto other hosts (let
  954. X.I finger
  955. Xdo the walking!!)
  956. X.TP 15
  957. X.B /help
  958. Xdisplay short help message.
  959. X.TP 15
  960. X.B /its
  961. Xoutput date and time more like the MIT ITS NAME program.  Changes
  962. X-What- header to Jobnam.
  963. X.TP 15
  964. X.B /location
  965. XIgnore user set ttyloc.
  966. X.TP 15
  967. X.B /mail-check
  968. XTalk about age of mail file (by default mail information is only
  969. Xprinted for logged out users), and mail forwarding.
  970. X.TP 15
  971. X.B /noinquire
  972. XDo not consult the inquire database (if present).
  973. X.TP 15
  974. X.B /noplan
  975. XDo not display .plan files ever (by default .plan files are shown for
  976. Xusers matched by name but not logged in).
  977. X.TP 15
  978. X.B /nosave-nlist
  979. XProhibit rewriting
  980. X.I /etc/finger-saved-nlist.
  981. XIf
  982. X.I finger
  983. Xis invoked as
  984. X.I xf
  985. Xthis is on by default.
  986. X.TP 15
  987. X.B /output-idle
  988. XShow idle time since last output to terminal.
  989. X.TP 15
  990. X.B /plan-check
  991. XForce printing of plan files for all users displayed (by default plans
  992. Xare only printed for logged out users matched by name).
  993. X.TP 15
  994. X.B /pid
  995. XDisplay pid of "current" process.
  996. X.TP 15
  997. X.B /read-nlist
  998. XForce read of
  999. X.I /vmunix
  1000. Xnamelist.
  1001. X.TP 15
  1002. X.B /short
  1003. XGive
  1004. X.I whoj
  1005. X(extra short format) output. Also
  1006. X.B /whoj.
  1007. X.TP 15
  1008. X.B /user-match
  1009. XMatch arguments only on user name. Also
  1010. X.B /match-user.
  1011. X.TP 15
  1012. X.B /version
  1013. XDisplay version and build information.
  1014. X.TP 15
  1015. X.B /whois
  1016. XGive
  1017. X.I whois
  1018. X(personal information) output. Implies
  1019. X.B /mail.
  1020. X.PP
  1021. XSome options are
  1022. X.I per-user
  1023. Xif they appear
  1024. X.B directly
  1025. Xafter a user (with no intervening spaces). For example;
  1026. X.br
  1027. X.I "finger tower/match budne"
  1028. Xshows only user
  1029. X.I tower
  1030. Xbut shows all users with last name budne.  The following options are
  1031. Xper-user:
  1032. X.BR location ,
  1033. X.BR mail ,
  1034. X.BR match ,
  1035. X.BR noplan ,
  1036. X.BR plan .
  1037. X
  1038. X.PP
  1039. XIt is possible to set up psuedo-users which are programs run instead
  1040. Xof the normal
  1041. X.I finger.
  1042. XThese have the string "RC" (exactly) in their GECOS field. Finger
  1043. Xchanges to their 'home' directory and expects there to be a program
  1044. Xwith the same name as the user. For example:
  1045. X
  1046. X.ce 1
  1047. Xuusnap:(*none*):1000:1000:RC:/usr/bin: 
  1048. X
  1049. X.PP
  1050. XWill cause
  1051. X.I finger lpq
  1052. Xto display the line printer queue rather than the normal
  1053. X.I finger
  1054. Xlisting.  This is particularly useful for remote machines (eg.
  1055. X.IR "finger uusnap@bu.edu" )
  1056. XBefore running the program
  1057. X.I finger
  1058. Xwill
  1059. X.IR setuid (2)
  1060. Xand
  1061. X.IR setgid (2)
  1062. Xto the psuedo-user's uid and group.
  1063. X.PP
  1064. X.SH FILES
  1065. X.ta 1.8i
  1066. X.nf
  1067. X/etc/utmp    who file
  1068. X/etc/passwd    for user names, offices
  1069. X/etc/nttyloc    for per-line system default ttylocs (new format)
  1070. X/etc/ttyloc    for per-line system default ttylocs (old format)
  1071. X/etc/ttys    Used under BSD 4.3 as last ditch for location
  1072. X/etc/ttytab    Used under SunOS 4 as last ditch for location
  1073. X/usr/adm/lastlog    last login times
  1074. X/usr/spool/mail    user mail files
  1075. X/usr/spool/ttyloc    user set ttyloc files
  1076. X~user/.forward    user mail address
  1077. X~user/.project    user projects
  1078. X~user/.plan    user plans
  1079. X.fi
  1080. X.ta
  1081. X.SH "SEE ALSO"
  1082. X.IR w (1),
  1083. X.IR who (1),
  1084. X.IR mesg (1),
  1085. X.IR hungry (1),
  1086. X.IR ttyloc (1),
  1087. X.IR nttyloc (5),
  1088. X.IR passwd (5),
  1089. X.IR utmp (5),
  1090. X.IR fingerd (8c)
  1091. X.SH AUTHOR
  1092. XPhilip L. Budne
  1093. X.SH BUGS
  1094. XShould show last
  1095. X.RB log out
  1096. Xtime, but there is no easy way to obtain it.
  1097. X.PP
  1098. XThis is even more of a pain in an NFS cluster, since each server and
  1099. Xclient maintain their own lastlog file.  What should be done is to
  1100. Xmodify
  1101. X.IR init (8), rlogind (8c),
  1102. Xand
  1103. X.IR telnetd (8c)
  1104. Xto write into a common (NFS) file containing login, logout, and host.
  1105. XAnother tact would be to have
  1106. X.IR login (1)
  1107. Xfork your shell, wait for exit and then write logout time.  Perhaps
  1108. Xlast logout should be added to the
  1109. X.I inquire
  1110. Xdatabase.
  1111. X.PP
  1112. XWhile
  1113. X.I finger
  1114. Xendeavors to show the correct program (it does better than
  1115. X.IR w (1)
  1116. Xby looking at process groups) it can fail.  Users of
  1117. X.IR sh (1)
  1118. Xmay have the most recent (highest numbered pid) fork displayed (ie;
  1119. X.IR more (1)
  1120. Xwill show up instead of the program which forked it.)
  1121. X.PP
  1122. XUnder Encore UMAX this will happen to csh users too if they user set
  1123. X.I mesg n
  1124. X(must be open the terminal for write in order to determine the
  1125. Xterminal process group number).
  1126. END_OF_finger.1
  1127. if test 6690 -ne `wc -c <finger.1`; then
  1128.     echo shar: \"finger.1\" unpacked with wrong size!
  1129. fi
  1130. # end of overwriting check
  1131. fi
  1132. if test -f getent.c -a "${1}" != "-c" ; then 
  1133.   echo shar: Will not over-write existing file \"getent.c\"
  1134. else
  1135. echo shar: Extracting \"getent.c\" \(4976 characters\)
  1136. sed "s/^X//" >getent.c <<'END_OF_getent.c'
  1137. X/*
  1138. X * getent.c -- build local user tree for finger
  1139. X * It all started here.. (November 1985)
  1140. X *
  1141. X * Copyright (C) 1986, 1990  Philip L. Budne
  1142. X *
  1143. X * This file is part of "Phil's Finger Program".
  1144. X *
  1145. X * This program is free software; you can redistribute it and/or modify
  1146. X * it under the terms of the GNU General Public License as published by
  1147. X * the Free Software Foundation; either version 1, or (at your option)
  1148. X * any later version.
  1149. X *
  1150. X */
  1151. X
  1152. X# ifndef lint
  1153. Xstatic char *rcsid = "$Id: getent.c,v 3.0 90/07/06 13:10:48 budd Rel $";
  1154. X# endif /* lint not defined */
  1155. X
  1156. X# include <sys/types.h>
  1157. X# include <utmp.h>
  1158. X# include <stdio.h>
  1159. X# include <ctype.h>
  1160. X# include "person.h"
  1161. X# include "args.h"            /* for luser.h */
  1162. X# include "luser.h"
  1163. X# include "tsel.h"
  1164. X# include "finger.h"
  1165. X
  1166. Xextern struct utmp *getutent();        /* from utmp.c */
  1167. Xextern endutent();            /* from utmp.c */
  1168. Xextern LUSER *treefind();        /* from getperson.c */
  1169. X
  1170. XFORWARD GLOBAL LUSER *linsert();
  1171. XFORWARD LOCAL  LUSER *mkluser();
  1172. X
  1173. XLOCAL TSEL *first_tsel, *last_tsel;
  1174. X
  1175. X# define LINESIZE sizeof( ((struct utmp *)0)->ut_line )    /* size of ut_line */
  1176. X
  1177. X/* .see gtname() in output.c */
  1178. X# define TTY_PREFIX "tty"
  1179. X# define TTY_PREFIX_SIZE (sizeof(TTY_PREFIX)-1)
  1180. X
  1181. X
  1182. XGLOBAL void init_tsel() {
  1183. X    first_tsel = last_tsel = NULL;
  1184. X}
  1185. X
  1186. XGLOBAL void addtty( s )
  1187. X    char *s;
  1188. X{
  1189. X    register TSEL *ts;
  1190. X    register l, l2;
  1191. X    if( (ts = (TSEL *) malloc( sizeof( TSEL ) )) == NULL ) {
  1192. X    perror("could not allocate tty selector");
  1193. X    exit( 1 );
  1194. X    }
  1195. X
  1196. X    l = l2 = strlen( s );
  1197. X    if( l > LINESIZE ) {
  1198. X    l = LINESIZE;
  1199. X    if( l > LINESIZE - TTY_PREFIX_SIZE )
  1200. X        l2 = l - TTY_PREFIX_SIZE;
  1201. X    }
  1202. X
  1203. X    ts->ts_name = s;
  1204. X    ts->ts_len = l;
  1205. X    ts->ts_len2 = l2;
  1206. X    ts->ts_next = NULL;
  1207. X    if( first_tsel == NULL )
  1208. X    first_tsel = last_tsel = ts;
  1209. X    else {
  1210. X    last_tsel->ts_next = ts;
  1211. X    last_tsel = ts;
  1212. X    }
  1213. X}
  1214. X
  1215. XGLOBAL LTREE *maketree() {        /* create tree of users */
  1216. X    register struct utmp *ut;
  1217. X    LTREE *tree;
  1218. X    LUSER *new;
  1219. X
  1220. X    tree = NULL;
  1221. X
  1222. X    while( (ut = getutent()) != NULL ) {
  1223. X
  1224. X    if( ut->ut_name[0] == EOS )    /* entry has name? */
  1225. X         continue;            /* no, get next */
  1226. X
  1227. X    if( first_tsel != NULL ) {
  1228. X        register TSEL *t;
  1229. X        int ok;
  1230. X
  1231. X        ok = FALSE;
  1232. X        for( t = first_tsel; t != NULL; t = t->ts_next ) {
  1233. X        if( strncmp( ut->ut_line, t->ts_name, t->ts_len ) == 0 ||
  1234. X           (strncmp( ut->ut_line, TTY_PREFIX, TTY_PREFIX_SIZE ) == 0 &&
  1235. X            strncmp( &ut->ut_line[TTY_PREFIX_SIZE],
  1236. X                t->ts_name, t->ts_len2 ) == 0) ){
  1237. X            ok = TRUE;
  1238. X            break;
  1239. X        } /* if strncmp */
  1240. X        } /* for */
  1241. X        if( !ok )
  1242. X        continue;
  1243. X    } /* first_tsel */
  1244. X
  1245. X    new = mkluser(ut);
  1246. X    tree = linsert(new, tree);
  1247. X    }
  1248. X    endutent();
  1249. X    return( tree );
  1250. X} /* maketree */
  1251. X
  1252. XGLOBAL LTREE *linsert(new, tree)     /* insert new user into tree */
  1253. Xregister LUSER *new;
  1254. Xregister LTREE *tree;
  1255. X{
  1256. X    if( tree == NULL )            /* empty tree. return new entry */
  1257. X        return( new );
  1258. X
  1259. X    if( strcmp(new->u_user, tree->u_user) < 0 ) /* less than root? */
  1260. X     tree->u_left = (LUSER *)linsert(new, tree->u_left); /* put on left */
  1261. X    else
  1262. X         tree->u_right = (LUSER *)linsert(new, tree->u_right);/* put on right */
  1263. X                    /* dupes are added to right */
  1264. X                    /* (.see pwtree) because we assume */
  1265. X                    /* that the utmp file is in tty name */
  1266. X                    /* order */
  1267. X
  1268. X    return( tree );            /* return the tree */
  1269. X}
  1270. X
  1271. XGLOBAL LUSER *newluser() {        /* create empty luser struct */
  1272. X    register LUSER *new;
  1273. X
  1274. X    if( (new = (LUSER *)malloc( sizeof( LUSER ) )) == NULL ) {
  1275. X    fprintf(stderr, "malloc failed in newluser\n");
  1276. X    exit( 1 );
  1277. X    }
  1278. X    new->u_person = NULL;
  1279. X    new->u_left = new->u_right = NULL;
  1280. X    new->u_flags = 0;
  1281. X    new->u_sw = Sw;            /* get per-person switches */
  1282. X    return( new );
  1283. X} /* newluser */
  1284. X
  1285. XLOCAL LUSER *mkluser( ut )        /* create a luser from utmp */
  1286. Xregister struct utmp *ut;
  1287. X{
  1288. X    register LUSER *new;
  1289. X
  1290. X    new = newluser();
  1291. X
  1292. X    strzcpy(new->u_user, ut->ut_name, sizeof(ut->ut_name) );
  1293. X    strzcpy(new->u_line, ut->ut_line, sizeof(ut->ut_line) );
  1294. X# ifndef UTMP_NO_HOST
  1295. X    strzcpy(new->u_host, ut->ut_host, sizeof(ut->ut_host) );
  1296. X# endif /* UTMP_NO_HOST not defined */
  1297. X    new->u_time = ut->ut_time;
  1298. X
  1299. X    return( new );
  1300. X} /* mkluser */
  1301. X
  1302. X/*
  1303. X * here with tree of usernames from command line
  1304. X * return new tree of logged in users
  1305. X */
  1306. X
  1307. XGLOBAL LTREE *ent_select( proto )
  1308. XLUSER *proto;
  1309. X{
  1310. X    register struct utmp *ut;
  1311. X    char name[ sizeof( ut->ut_name ) + 1 ];
  1312. X    LUSER *new, *found;
  1313. X    LTREE *t2;
  1314. X
  1315. X    t2 = NULL;
  1316. X
  1317. X    while( (ut = getutent()) != NULL ) {
  1318. X    if( ut->ut_name[0] == EOS )    /* entry has name? */
  1319. X        continue;            /* no, get next */
  1320. X
  1321. X    strzcpy( name, ut->ut_name, sizeof( ut->ut_name ) );
  1322. X    if( (found = treefind( proto, name )) != NULL ) {
  1323. X        register PERSON *p;
  1324. X
  1325. X        found->u_flags |= U_FOUND;
  1326. X        new = mkluser(ut);
  1327. X        p = new->u_person = found->u_person;
  1328. X        if( p != NULL )
  1329. X        p->p_count++;
  1330. X        t2 = linsert(new, t2);
  1331. X    } /* found template */
  1332. X    } /* while utmp */
  1333. X    endutent();
  1334. X
  1335. X    return( t2 );
  1336. X} /* ent_select */
  1337. X
  1338. X/*
  1339. X * Local variables:
  1340. X * comment-column: 40
  1341. X * End:
  1342. X */
  1343. END_OF_getent.c
  1344. if test 4976 -ne `wc -c <getent.c`; then
  1345.     echo shar: \"getent.c\" unpacked with wrong size!
  1346. fi
  1347. # end of overwriting check
  1348. fi
  1349. if test -f mcheck.c -a "${1}" != "-c" ; then 
  1350.   echo shar: Will not over-write existing file \"mcheck.c\"
  1351. else
  1352. echo shar: Extracting \"mcheck.c\" \(4934 characters\)
  1353. sed "s/^X//" >mcheck.c <<'END_OF_mcheck.c'
  1354. X/*
  1355. X * mcheck.c -- check for mail
  1356. X *
  1357. X * Copyright (C) 1986, 1990  Philip L. Budne
  1358. X *
  1359. X * This file is part of "Phil's Finger Program".
  1360. X *
  1361. X * This program is free software; you can redistribute it and/or modify
  1362. X * it under the terms of the GNU General Public License as published by
  1363. X * the Free Software Foundation; either version 1, or (at your option)
  1364. X * any later version.
  1365. X *
  1366. X */
  1367. X
  1368. X# ifndef lint
  1369. Xstatic char *rcsid = "$Id: mcheck.c,v 3.0 90/07/06 13:11:19 budd Rel $";
  1370. X# endif /* lint not defined */
  1371. X
  1372. X# include <sys/types.h>
  1373. X# include <sys/stat.h>
  1374. X# include <strings.h>
  1375. X# include <errno.h>
  1376. X# include <stdio.h>
  1377. X# include <ctype.h>
  1378. X# include "person.h"
  1379. X# include "args.h"            /* before luser.h */
  1380. X# include "luser.h"
  1381. X# include "finger.h"
  1382. X
  1383. Xextern void add4n();            /* from args.c */
  1384. X
  1385. X/*
  1386. X *    it is possible to detect aliasing by invoking sendmail -bv
  1387. X *    <user>. This checks .forward files too!!  but is of little use
  1388. X *    when the current host is a workstation or other mail moron
  1389. X *    that hands off all work to a server.
  1390. X *
  1391. X *    "ypmatch <user> aliases" DOES work, but no functions 
  1392. X *    are provided to access the mail.alias yp map.  TODO
  1393. X */
  1394. X
  1395. X# define LEN 1024
  1396. XGLOBAL void mcheck( u )
  1397. XLUSER *u;
  1398. X{
  1399. X# ifdef MAIL_SPOOL
  1400. X    BOOL nomailbox;
  1401. X    char fname[LEN];
  1402. X    struct stat stb;
  1403. X    extern int errno;
  1404. X    extern char *sys_errlist[];
  1405. X
  1406. X# ifdef AIX_PS2
  1407. X    if( u->u_person == NULL )
  1408. X    return;
  1409. X    strcpy(fname, u->u_person->p_home );
  1410. X    strcat(fname, "/.newmail");
  1411. X# else  /* AIX_PS2 not defined */
  1412. X    strcpy(fname, MAIL_SPOOL );
  1413. X    strcat(fname, "/");
  1414. X    strcat(fname, u->u_user );
  1415. X# endif /* AIX_PS2 not defined */
  1416. X
  1417. X    nomailbox = FALSE;
  1418. X    if( stat(fname, &stb) != 0 ) {
  1419. X    switch( errno ) {
  1420. X        case ENOENT:
  1421. X        nomailbox = TRUE;
  1422. X        break;
  1423. X
  1424. X    case EPERM:
  1425. X        outline("  [Mail file protected]");
  1426. X        break;
  1427. X
  1428. X    default:
  1429. X        sprintf(fname, "  [Funny mail file error (%s)]",
  1430. X            sys_errlist[errno] );
  1431. X        outline( fname );
  1432. X    } /* switch */
  1433. X    } /* stat failed */
  1434. X    else {                /* stat ok */
  1435. X    if( stb.st_size > 0  &&  stb.st_mtime >= stb.st_atime ) {
  1436. X        sprintf(fname, "  %s has new mail as of %s",
  1437. X            u->u_user, nicetime( stb.st_mtime ) );
  1438. X
  1439. X        if( stb.st_atime != stb.st_ctime ) { /* read since created */
  1440. X        outline( fname );    /* output previous line */
  1441. X        sprintf(fname, "  last read %s", nicetime( stb.st_atime ) );
  1442. X        }
  1443. X    }
  1444. X    else                /* empty or access after modify */
  1445. X        sprintf(fname, "  %s has no new mail, last read %s",
  1446. X            u->u_user, nicetime( stb.st_atime ) );
  1447. X    outline( fname );
  1448. X    } /* stat ok */
  1449. X
  1450. X    if( u->u_person != NULL && u->u_person->p_maddr != NULL ) {
  1451. X    sprintf(fname, "  [%s is forwarded to %s]",
  1452. X        (nomailbox ? "Mail" : "New mail"),
  1453. X        u->u_person->p_maddr );
  1454. X    outline( fname );
  1455. X    }
  1456. X    else if( nomailbox )
  1457. X    outline("  [No mail file]");
  1458. X# endif /* MAIL_SPOOL defined */
  1459. X} /* mcheck */
  1460. X
  1461. X/**** THIS IS GROSS ****/
  1462. X
  1463. XGLOBAL void maddr( p, uname )        /* get mailing address */
  1464. X    PERSON *p;
  1465. X    char *uname;            /* for possible alias hackery */
  1466. X{
  1467. X    register char *dp, *xp, *ap;
  1468. X    char fname[ LEN ], obuf[ LEN*3 ], *sp;
  1469. X    int room;
  1470. X    FILE *f;
  1471. X
  1472. X    /* try yp_match( domain, "mail.alias", name, namelen, valp, vallenp ) */
  1473. X
  1474. X    strcpy( fname, p->p_home );
  1475. X    strcat( fname, "/.forward" );
  1476. X    f = fopen( fname, "r" );
  1477. X    if( f == NULL )
  1478. X    return;
  1479. X
  1480. X    dp = obuf;                /* set dest ptr */
  1481. X    room = sizeof( obuf );
  1482. X    while( fgets( fname, sizeof( fname ), f ) != NULL ) {
  1483. X    sp = fname;            /* set src ptr */
  1484. X
  1485. X    for( ; ; ) {
  1486. X        if( !skipwhite( &sp ) )    /* eat whitespace */
  1487. X        break;            /* nothing left? */
  1488. X
  1489. X        /* check for " / | \ */
  1490. X        if( room > 0 &&dp != obuf ) { /* not the first? */
  1491. X        *dp++ = ',';
  1492. X        room--;
  1493. X        }
  1494. X
  1495. X        xp = sp;            /* save start of addr */
  1496. X        while( *sp != EOS && !isspace( *sp ) && *sp != ',' )
  1497. X        if( --room > 0 )
  1498. X            *dp++ = *sp++;    /* copy while not white */
  1499. X
  1500. X        if( *sp != EOS )        /* if not end of source */
  1501. X        *sp++ = EOS;        /* tie off (blast/skip punct) */
  1502. X
  1503. X        if( sw_follow ) {
  1504. X        if( (ap = rindex( xp, '@' )) != NULL ) /* have a host? */
  1505. X            *ap++ = EOS;    /* tie off host */
  1506. X
  1507. X        if( *xp == '\\' )    /* backslash quoted username? */
  1508. X            xp++;        /* skip bs */
  1509. X
  1510. X        if( *xp != '|' && *xp != '/' ) { /* not pipe or file */
  1511. X            char *pp;        /* percent ptr */
  1512. X
  1513. X            /* perhaps blast only the rightmost %? */
  1514. X            pp = xp;        /* blast all %'s in user into @'s */
  1515. X            while( (pp = index(pp, '%')) != NULL )
  1516. X            *pp++ = '@';
  1517. X
  1518. X            if( ap != NULL && !islocalhost(ap) )
  1519. X            add4n(savestr(xp), savestr(ap) ); /* user, host */
  1520. X            else if( strcmp( xp, uname ) != 0 ) { /* not me? */
  1521. X            struct switches SavedSw;
  1522. X            SavedSw = Sw;
  1523. X            Sw.sw_match = TRUE;
  1524. X            addlocal( savestr(xp) );
  1525. X            Sw = SavedSw;
  1526. X            }
  1527. X        } /* not pipe or file */
  1528. X        } /* sw_follow */
  1529. X    } /* for ever */
  1530. X    } /* read ok */
  1531. X    *dp = EOS;                /* tie off */
  1532. X
  1533. X    p->p_maddr = savestr( obuf );    /* fill in person's mailing address */
  1534. X
  1535. X    close( f );
  1536. X} /* maddr */
  1537. X
  1538. X/*
  1539. X * Local variables:
  1540. X * comment-column: 40
  1541. X * End:
  1542. X */
  1543. END_OF_mcheck.c
  1544. if test 4934 -ne `wc -c <mcheck.c`; then
  1545.     echo shar: \"mcheck.c\" unpacked with wrong size!
  1546. fi
  1547. # end of overwriting check
  1548. fi
  1549. if test -f read_vmunix.c -a "${1}" != "-c" ; then 
  1550.   echo shar: Will not over-write existing file \"read_vmunix.c\"
  1551. else
  1552. echo shar: Extracting \"read_vmunix.c\" \(5605 characters\)
  1553. sed "s/^X//" >read_vmunix.c <<'END_OF_read_vmunix.c'
  1554. X/*
  1555. X * read_vmunix.c -- read data from an a.out file (for kernel _version)
  1556. X *    This is just awful!!
  1557. X *
  1558. X * Copyright (C) 1986, 1990  Philip L. Budne
  1559. X *
  1560. X * This file is part of "Phil's Finger Program".
  1561. X *
  1562. X * This program is free software; you can redistribute it and/or modify
  1563. X * it under the terms of the GNU General Public License as published by
  1564. X * the Free Software Foundation; either version 1, or (at your option)
  1565. X * any later version.
  1566. X *
  1567. X */
  1568. X
  1569. X# ifndef lint
  1570. Xstatic char *rcsid = "$Id: read_vmunix.c,v 3.0 90/07/06 13:11:37 budd Rel $";
  1571. X# endif /* lint not defined */
  1572. X
  1573. X# include "finger.h"
  1574. X# if Umax != 42 && !defined(USG)
  1575. X
  1576. X# include "args.h"
  1577. X# ifndef COFF                /* good old a.out */
  1578. X
  1579. X# include <a.out.h>
  1580. X
  1581. X/*
  1582. X *    N_SEGSIZ is only needed if the kernel is not an OMAGIC file.
  1583. X */
  1584. X
  1585. X# ifdef sun
  1586. X
  1587. X# define LMASK 0xfff            /* crock, seems to work tho */
  1588. X                    /* for Sun2,3,4 */
  1589. X/*# define LOADADDR 0xff004000        /* sun4 */
  1590. X/*# define LOADADDR 0x0f004000        /* sun3 */
  1591. X/*# define LOADADDR     0x4000        /* sun2 */
  1592. X# endif /* sun defined */
  1593. X
  1594. X# ifdef accel
  1595. X# define LMASK 0xffff
  1596. X# define INCLUDE_HEADERS
  1597. X# endif /* accel defined */
  1598. X
  1599. X# ifndef N_SEGSIZ            /* a sun-ism */
  1600. X# include <sys/param.h>            /* get CLBYTES */
  1601. X# define N_SEGSIZ(a) (CLBYTES)        /* simulate sun macro */
  1602. X# endif /* N_SEGSIZ not defined */
  1603. X
  1604. X# ifdef vax
  1605. X# define LOADADDR 0x80000000        /* kernel load address */
  1606. X# endif /* vax defined */
  1607. X
  1608. X# ifdef ibm032                /* RT under AOS/ACIS 4.3 */
  1609. X# define LOADADDR 0xe0000000        /* kernel load address */
  1610. X# endif /* ibm032 defined */
  1611. X
  1612. X# ifdef sony_news            /* only tested for News-800 */
  1613. X# define LOADADDR 0x80001000        /* crocked by 4k? */
  1614. X# endif /* sony_news defined */
  1615. X
  1616. X# ifdef sequent                /* only tested for S3 */
  1617. X# define LOADADDR 0
  1618. X# endif /* sequent defined */
  1619. X
  1620. XGLOBAL BOOL
  1621. Xread_vmunix( file, off, str, len )
  1622. Xchar *file;                /* file name */
  1623. Xlong off;                /* virtual address */
  1624. Xchar *str;                /* dest buffer */
  1625. Xint len;                /* chars to read */
  1626. X{
  1627. X    int f;
  1628. X    long pos, base, data, koffset;
  1629. X    struct exec ex;
  1630. X
  1631. X    if( off == 0L )            /* bogus offset */
  1632. X    return( FALSE );        /* lose quickly */
  1633. X
  1634. X    if( (f = open( file, 0 )) < 0 )    /* open /vmunix */
  1635. X    return( FALSE );        /* you lose */
  1636. X
  1637. X    if( read( f, &ex, sizeof( ex ) ) != sizeof( ex ) ) { /* read header */
  1638. X    close( f );            /* short read */
  1639. X    return( FALSE );        /* quit */
  1640. X    }
  1641. X
  1642. X    base = N_TXTOFF( ex );        /* get start of meaningfullness */
  1643. X
  1644. X# ifdef LOADADDR
  1645. X    koffset = LOADADDR;            /* offset into image */
  1646. X# else  /* LOADADDR not defined */
  1647. X# ifdef LMASK
  1648. X    koffset = ex.a_entry & ~LMASK;
  1649. X# else  /* LMASK not defined */
  1650. X# include <ERROR: must have one of LOADADDR and LMASK>
  1651. X# endif /* LMASK not defined */
  1652. X# endif /* LOADADDR not defined */
  1653. X
  1654. X    off -= koffset;            /* remove kernel offset */
  1655. X    if( ex.a_magic == OMAGIC
  1656. X# ifdef NMAGIC                /* sequent lacks NMAGIC! */
  1657. X       || (off < ex.a_text && ex.a_magic == NMAGIC)
  1658. X# endif /* NMAGIC defined */
  1659. X# ifdef SMAGIC                /* sequent standalone */
  1660. X    || ex.a_magic == SMAGIC
  1661. X# endif /* SMAGIC defined */
  1662. X    ) /* OMAGIC or NMAGIC text */
  1663. X    data = 0;            /* no data offset */
  1664. X# ifdef NMAGIC
  1665. X    else if( ex.a_magic == NMAGIC ) {    /* NMAGIC data loaded on seg boundry */
  1666. X    int segs;            /* segment size */
  1667. X    segs = N_SEGSIZ(ex) - 1;    /* round to "segment" after text*/
  1668. X    data = (ex.a_text + segs - 1) & ~segs;
  1669. X    data -= ex.a_text;        /* just get needed offset */
  1670. X    }
  1671. X# endif /* NMAGIC defined */
  1672. X# ifdef SOME_DAY_OVER_THE_RAINBOW
  1673. X    else if( ex.a_magic == ZMAGIC ) {    /* never seen a ZMAGIC kernel!! */
  1674. X    base = N_SEGSIZ(ex);        /* text starts on page boundry */
  1675. X    if( off >= ex.a_text ) {
  1676. X        /* something like for NMAGIC above... */
  1677. X    }
  1678. X    } /* ZMAGIC */
  1679. X# endif /* SOME_DAY_OVER_THE_RAINBOW defined */
  1680. X    else {
  1681. X# ifdef DEBUGSW
  1682. X     if( sw_debug )
  1683. X        printf("Unknown %s magic %#x %#o\n", KERNEL_FILE,
  1684. X        ex.a_magic, ex.a_magic );
  1685. X# endif /* DEBUGSW defined */
  1686. X    return( FALSE );        /* (bad magic falls here too) */
  1687. X    }
  1688. X
  1689. X    pos = off + base - data;
  1690. X# ifdef DEBUGSW
  1691. X    if( sw_debug )
  1692. X    printf("read_vmunix: pos %#x off %#x base %#x data %#x\n",
  1693. X           pos, off, base, data );
  1694. X# endif /* DEBUGSW defined */
  1695. X
  1696. X    if( lseek( f, pos, 0 ) == pos &&    /* seek to position */
  1697. X       read( f, str, len ) == len ) {    /* and read bytes */
  1698. X    close( f );            /* ok!! */
  1699. X    return( TRUE );            /* return good status */
  1700. X    } /* lseek and read OK */
  1701. X    close( f );
  1702. X    return( FALSE );
  1703. X} /* read_vmunix */
  1704. X
  1705. X# else  /* COFF defined */
  1706. X
  1707. X/*
  1708. X *    BSD systems using COFF end up here
  1709. X *    ie; DECstation3100 and Sun 386i
  1710. X *
  1711. X *    *TODO* needs work!
  1712. X */
  1713. X
  1714. X# include <stdio.h>
  1715. X# include <filehdr.h>
  1716. X# include <syms.h>            /* works for DS3100. 386i?? */
  1717. X# include <ldfcn.h>
  1718. X
  1719. X# ifndef ISCOFF
  1720. X/* UGH! This happens only on Umax 4.3 */
  1721. X# define ISCOFF(m) ((m) >= 0500 && (m) <= 0577)
  1722. X# endif /* ISCOFF not defined */
  1723. X
  1724. XGLOBAL BOOL
  1725. Xread_vmunix( file, off, str, len )    /* Hacking cough... */
  1726. X    char *file;                /* file name */
  1727. X    long off;                /* virtual address */
  1728. X    char *str;                /* dest buffer */
  1729. X    int len;                /* chars to read */
  1730. X{
  1731. X    LDFILE *ld;
  1732. X
  1733. X# ifdef DEBUGSW
  1734. X    if( sw_debug )
  1735. X        printf("read_vmunix('%s', %x, ... , %d)\n", file, off, len );
  1736. X# endif /* DEBUGSW defined */
  1737. X
  1738. X    if( (ld = ldopen(file, NULL)) == NULL )
  1739. X    return( FALSE );
  1740. X
  1741. X    for( ; ; ) {            /* bogus loop */
  1742. X    if( !ISCOFF( HEADER(ld).f_magic ) )
  1743. X        break;
  1744. X
  1745. X# ifdef DEBUGSW
  1746. X    if( sw_debug )
  1747. X        puts("got here");
  1748. X# endif /* DEBUGSW defined */
  1749. X
  1750. X    /* more good stuff here! */
  1751. X
  1752. X    break;                /* break bogus loop! */
  1753. X    } /* bogus for loop */
  1754. X    ldclose( ld );
  1755. X    return( FALSE );
  1756. X} /* read_vmunix */
  1757. X# endif /* COFF defined */
  1758. X
  1759. X# endif /* Umax != 42 && !defined(USG) */
  1760. X
  1761. X/*
  1762. X * Local variables:
  1763. X * comment-column: 40
  1764. X * End:
  1765. X */
  1766. END_OF_read_vmunix.c
  1767. if test 5605 -ne `wc -c <read_vmunix.c`; then
  1768.     echo shar: \"read_vmunix.c\" unpacked with wrong size!
  1769. fi
  1770. # end of overwriting check
  1771. fi
  1772. if test -f ttylocfile.c -a "${1}" != "-c" ; then 
  1773.   echo shar: Will not over-write existing file \"ttylocfile.c\"
  1774. else
  1775. echo shar: Extracting \"ttylocfile.c\" \(6076 characters\)
  1776. sed "s/^X//" >ttylocfile.c <<'END_OF_ttylocfile.c'
  1777. X/*
  1778. X * ttylocfile.c -- read /etc/ttyloc and /etc/nttyloc (December 1985)
  1779. X *
  1780. X * Copyright (C) 1986, 1990  Philip L. Budne
  1781. X *
  1782. X * This file is part of "Phil's Finger Program".
  1783. X *
  1784. X * This program is free software; you can redistribute it and/or modify
  1785. X * it under the terms of the GNU General Public License as published by
  1786. X * the Free Software Foundation; either version 1, or (at your option)
  1787. X * any later version.
  1788. X *
  1789. X */
  1790. X
  1791. X# ifndef lint
  1792. Xstatic char *rcsid = "$Id: ttylocfile.c,v 3.0 90/07/06 13:12:03 budd Rel $";
  1793. X# endif /* lint not defined */
  1794. X
  1795. X# include "finger.h"
  1796. X# include <sys/types.h>
  1797. X# include <stdio.h>
  1798. X# ifdef TTYENT
  1799. X# include <ttyent.h>
  1800. X# endif /* TTYENT defined */
  1801. X
  1802. X# include "ttylocfile.h"
  1803. X
  1804. X# define BUFSIZE 512
  1805. X
  1806. XLOCAL TTYLOC ttyloc[MAXTTY];
  1807. XLOCAL int nttyloc;
  1808. X
  1809. XLOCAL int ttyloc_compare( a, b )    /* comparison for qsorting ttyloc[] */
  1810. X    register struct ttyloc *a, *b;
  1811. X{
  1812. X    return strcmp( a->t_name, b->t_name );
  1813. X} /* ttyloc_compare */
  1814. X
  1815. XGLOBAL int readnewttylocfile() {
  1816. X    FILE *fp;
  1817. X    char buf[BUFSIZE];
  1818. X    char *cp;
  1819. X    register char *sp;
  1820. X    register int c, q, l;
  1821. X    register struct ttyloc *tp;
  1822. X
  1823. X    nttyloc = 0;
  1824. X    if( (fp = fopen(NLOCFILE,"r")) == NULL )
  1825. X    return( 0 );            /* found none */
  1826. X
  1827. X    tp = ttyloc;            /* point to start of array */
  1828. X    while( nttyloc < MAXTTY && fgets(buf, BUFSIZE, fp) != NULL ) {
  1829. X    cp = buf;
  1830. X
  1831. X    tp->t_name = NULL;
  1832. X    tp->t_short = NULL;
  1833. X    tp->t_locn = NULL;
  1834. X    tp->t_type = LT_UNKNOWN;
  1835. X
  1836. X    l = strlen(cp);            /* smash nl into eos */
  1837. X    if( l > 0 && (buf[l-1] == '\n') )
  1838. X        buf[l-1] = EOS;
  1839. X
  1840. X    if( !skipwhite( &cp ) )
  1841. X        continue;
  1842. X
  1843. X    if( *cp == '#' )        /* comment line? */
  1844. X        continue;            /*  yes, skip it */
  1845. X
  1846. X    sp = cp;            /* get start of line type */
  1847. X    if( !skipblack( &cp ) )
  1848. X        continue;
  1849. X    *cp++ = EOS;
  1850. X
  1851. X    l = strlen( sp );
  1852. X    if( strncmp( sp, "hardwire", l ) == 0 )
  1853. X        tp->t_type = LT_HARD;
  1854. X    else if( strncmp( sp, "ttyloc", l ) == 0 )
  1855. X        tp->t_type = LT_TTYLOC;
  1856. X    else if( strncmp( sp, "dialup", l ) == 0 )
  1857. X        tp->t_type = LT_DIALUP;
  1858. X    else if( strncmp( sp, "random", l ) == 0 )
  1859. X        tp->t_type = LT_UNKNOWN;
  1860. X    else
  1861. X        continue;            /* you lose */
  1862. X
  1863. X    if( !skipwhite( &cp ) )
  1864. X        continue;
  1865. X    tp->t_name = cp;        /* save start of terminal name */
  1866. X    if( !skipblack( &cp ) )
  1867. X        continue;
  1868. X    *cp++ = EOS;
  1869. X
  1870. X    /* pick up short location */
  1871. X    if( *cp == '"' || *cp == '\'' ) {
  1872. X        q = *cp++;
  1873. X        sp = cp;
  1874. X        while( (c = *cp) != EOS && c != q )
  1875. X        cp++;
  1876. X        if( c == EOS )
  1877. X        continue;
  1878. X    }
  1879. X    else {
  1880. X        sp = cp;
  1881. X        if( !skipblack( &cp ) )
  1882. X        continue;
  1883. X    }
  1884. X    *cp++ = EOS;
  1885. X
  1886. X    tp->t_short = sp;
  1887. X
  1888. X    if( !skipwhite( &cp ) )
  1889. X        continue;
  1890. X
  1891. X    /* pick up long location */
  1892. X    if( *cp == '"' || *cp == '\'' ) {
  1893. X        q = *cp++;
  1894. X        sp = cp;
  1895. X        while( (c = *cp) != EOS && c != q )
  1896. X        cp++;
  1897. X        *cp++ = EOS;
  1898. X    }
  1899. X    else
  1900. X        sp = cp;
  1901. X
  1902. X    if( strlen( sp ) == 0 )        /* no long location? */
  1903. X        continue;            /* get lost */
  1904. X
  1905. X    tp->t_locn  = savestr( sp );
  1906. X    tp->t_name  = savestr( tp->t_name );
  1907. X    if( *tp->t_short != EOS )
  1908. X        tp->t_short = savestr( tp->t_short );
  1909. X    else
  1910. X        tp->t_short = NULL;
  1911. X
  1912. X    tp++;
  1913. X    nttyloc++;
  1914. X    } /* while fgets.. */
  1915. X    fclose(fp);
  1916. X    qsort( ttyloc, nttyloc, sizeof( ttyloc[0] ), ttyloc_compare );
  1917. X    return( nttyloc );
  1918. X} /* readnewttylocfile */
  1919. X
  1920. XGLOBAL int readttylocfile() {
  1921. X    FILE *fp;
  1922. X    char buf[BUFSIZE];
  1923. X    char *cp;
  1924. X    register int i;
  1925. X    register char *sp;
  1926. X    register struct ttyloc *tp;
  1927. X
  1928. X    nttyloc = 0;
  1929. X    if( (fp = fopen(LOCFILE,"r")) == NULL )
  1930. X    return( 0 );            /* found none */
  1931. X
  1932. X    tp = ttyloc;            /* point to start of array */
  1933. X    while( nttyloc < MAXTTY && fgets(buf, BUFSIZE, fp) != NULL ) {
  1934. X    cp = buf;
  1935. X
  1936. X    i = strlen(cp);            /* smash nl into eos */
  1937. X    if( i > 0 && (buf[i-1] == '\n') )
  1938. X        buf[i-1] = EOS;
  1939. X
  1940. X    if( !skipwhite( &cp ) )
  1941. X        continue;
  1942. X
  1943. X    if( *cp == '#' )        /* comment line? */
  1944. X        continue;            /*  yes, skip it */
  1945. X
  1946. X    sp = cp;
  1947. X    if( !skipblack( &cp ))
  1948. X        continue;
  1949. X
  1950. X    *cp++ = EOS;
  1951. X
  1952. X    tp->t_short = NULL;
  1953. X    tp->t_locn = NULL;
  1954. X    tp->t_type = LT_UNKNOWN;
  1955. X
  1956. X       if( strlen( cp ) > 0 ) {
  1957. X        tp->t_locn = savestr( cp );
  1958. X        tp->t_name = savestr( sp );
  1959. X        tp++;
  1960. X        nttyloc++;
  1961. X    }
  1962. X    } /* while fgets.. */
  1963. X    fclose(fp);
  1964. X    qsort( ttyloc, nttyloc, sizeof( ttyloc[0] ), ttyloc_compare );
  1965. X    return( nttyloc );
  1966. X} /* readttylocfile */
  1967. X
  1968. X# ifdef TTYENT
  1969. XGLOBAL int readttyents() {        /* 4.3/Ultrix ttys file */
  1970. X    register struct ttyent *ty;
  1971. X    register struct ttyloc *tp;
  1972. X
  1973. X    nttyloc = 0;
  1974. X    tp = ttyloc;
  1975. X    setttyent();
  1976. X    while( nttyloc < MAXTTY && (ty = getttyent()) != NULL ) {
  1977. X# ifndef USE_ALL_TTYENTS
  1978. X    if( (ty->ty_status & TTY_ON) == 0 )
  1979. X        continue;
  1980. X# endif /* USE_ALL_TTYENTS not defined */
  1981. X
  1982. X    tp->t_name = savestr( ty->ty_name ); /* save line name */
  1983. X
  1984. X# ifdef DONT_USE_TTYENT_TYPE_AS_SHORT
  1985. X    tp->t_short = NULL;
  1986. X# else  /* DONT_USE_TTYENT_TYPE_AS_SHORT not defined */
  1987. X    tp->t_short = savestr( ty->ty_type );
  1988. X# endif /* DONT_USE_TTYENT_TYPE_AS_SHORT not defined */
  1989. X
  1990. X    tp->t_locn = NULL;        /* assume the worst */
  1991. X    if( ty->ty_comment != NULL ) {
  1992. X        char *cp;
  1993. X
  1994. X        cp = ty->ty_comment;
  1995. X        if( *cp == '#' )        /* strip leading pound sign */
  1996. X        cp++;            /* (needed under uglix) */
  1997. X
  1998. X        while( *cp == ' ' || *cp == '\t' ) /* strip leading white */
  1999. X        cp++;
  2000. X
  2001. X        if( *cp != EOS )        /* anything left? */
  2002. X        tp->t_locn = savestr( cp ); /* yes, save as location */
  2003. X    } /* have comment */
  2004. X    tp->t_type = LT_UNKNOWN;
  2005. X    tp++;
  2006. X    nttyloc++;
  2007. X    } /* while */
  2008. X    endttyent();
  2009. X    qsort( ttyloc, nttyloc, sizeof( ttyloc[0] ), ttyloc_compare );
  2010. X    return( nttyloc );
  2011. X} /* readttyents */
  2012. X# endif /* TTYENT defined */
  2013. X
  2014. XGLOBAL TTYLOC *findttyloc( tty )    /* find entry in ttyloc file */
  2015. Xchar *tty;
  2016. X{
  2017. X    register int min, max, ptr;
  2018. X    register TTYLOC *tp;
  2019. X
  2020. X    min = 0;
  2021. X    max = nttyloc - 1;
  2022. X    while( min <= max ) {
  2023. X    int v;
  2024. X    ptr = (max + min + 1) >> 1;
  2025. X    tp = &ttyloc[ ptr ];
  2026. X    v = strcmp( tty, tp->t_name );
  2027. X# ifdef DEBUG
  2028. X    fprintf(stderr, "%d %d %d: %s,%s,%d\n",
  2029. X        min, ptr, max, tty, tp->t_name, v);
  2030. X# endif /* DEBUG defined */
  2031. X    if( v == 0 )
  2032. X        return( tp );
  2033. X    else if( v > 0 )
  2034. X        min = ptr + 1;
  2035. X    else
  2036. X        max = ptr - 1;
  2037. X    } /* while */
  2038. X    return( NULL );
  2039. X} /* findttyloc */
  2040. X
  2041. X/*
  2042. X * Local variables:
  2043. X * comment-column: 40
  2044. X * End:
  2045. X */
  2046. END_OF_ttylocfile.c
  2047. if test 6076 -ne `wc -c <ttylocfile.c`; then
  2048.     echo shar: \"ttylocfile.c\" unpacked with wrong size!
  2049. fi
  2050. # end of overwriting check
  2051. fi
  2052. if test -f undomain.c -a "${1}" != "-c" ; then 
  2053.   echo shar: Will not over-write existing file \"undomain.c\"
  2054. else
  2055. echo shar: Extracting \"undomain.c\" \(5512 characters\)
  2056. sed "s/^X//" >undomain.c <<'END_OF_undomain.c'
  2057. X/*
  2058. X * undomain.c -- massage host names
  2059. X *
  2060. X * Copyright (C) 1986, 1990  Philip L. Budne
  2061. X *
  2062. X * This file is part of "Phil's Finger Program".
  2063. X *
  2064. X * This program is free software; you can redistribute it and/or modify
  2065. X * it under the terms of the GNU General Public License as published by
  2066. X * the Free Software Foundation; either version 1, or (at your option)
  2067. X * any later version.
  2068. X *
  2069. X */
  2070. X
  2071. X# ifndef lint
  2072. Xstatic char *rcsid = "$Id: undomain.c,v 3.0 90/07/06 13:12:06 budd Rel $";
  2073. X# endif /* lint not defined */
  2074. X
  2075. X# include <stdio.h>            /* for NULL */
  2076. X# include <strings.h>            /* for (r)index */
  2077. X# include <ctype.h>            /* for isdigit() */
  2078. X# include <sys/types.h>            /* for socket.h */
  2079. X# include <sys/socket.h>        /* for AF_INET */
  2080. X# include <netdb.h>            /* for {host,net}ent structs */
  2081. X# include <arpa/inet.h>            /* for inet_.... */
  2082. X# include <netinet/in.h>        /* for in_addr */
  2083. X# include "finger.h"
  2084. X# include "upper.h"
  2085. X
  2086. X# if 1
  2087. X# define SCMP(a,b) casecmp(a,b)
  2088. X# define CCMP(a,b) TOUP(a) == TOUP(b)
  2089. X# define TOUP(c) uppercase[c&0177]
  2090. X# else  /* not 1 */
  2091. X# define SCMP(a,b) (strcmp(a,b) == 0)
  2092. X# define CCMP(a,b) a == b
  2093. X# endif /* not 1 */
  2094. X
  2095. Xextern char localhost[];        /* from args.c */
  2096. Xextern char OFFICIALhostname[];        /* from args.c */
  2097. X
  2098. Xextern char *conf_prefix();        /* from conf.c */
  2099. X
  2100. XLOCAL char *prefixes[] = {        /* read from init file? */
  2101. X                    /* Sorted by length?? */
  2102. X# ifdef PREFIXES
  2103. X    PREFIXES ,
  2104. X# endif /* PREFIXES defined */
  2105. X    NULL
  2106. X    };
  2107. X
  2108. XLOCAL BOOL tryprefix( hp, pp )
  2109. X    register char *pp, *hp;
  2110. X{
  2111. X    char *h;
  2112. X# ifdef DEBUG
  2113. X    printf("tryprefix(%s,%s)\n", hp, pp );
  2114. X# endif /* DEBUG defined */
  2115. X    h = hp;                /* save host buffer pointer */
  2116. X    while( CCMP(*hp,*pp) && *pp != EOS ) {
  2117. X    hp++;
  2118. X    pp++;
  2119. X    } /* while prefix matches */
  2120. X    if( *hp == EOS )            /* saw end of host first? */
  2121. X    return( FALSE );        /* ENTIRE hostname is a prefix?? */
  2122. X                    /* try next (shorter?) prefix */
  2123. X
  2124. X    if( *pp == EOS )            /* saw end of prefix */
  2125. X    strcpy( h, hp );        /* slide back (backwards overlap?) */
  2126. X
  2127. X    return( TRUE );
  2128. X} /* tryprefix */
  2129. X
  2130. XLOCAL void unprefix( h )
  2131. Xchar *h;
  2132. X{
  2133. X    char **ppp, *pp;
  2134. X    int i;
  2135. X
  2136. X    for( ppp = prefixes; *ppp != NULL; ppp++ )
  2137. X    if( tryprefix( h, *ppp ) )
  2138. X        return;
  2139. X
  2140. X    for( i = 0; (pp = conf_prefix(i)) != NULL; i++ )
  2141. X    if( tryprefix( h, pp ) )
  2142. X        return;
  2143. X} /* unprefix */
  2144. X
  2145. XGLOBAL void undomain( h, rem_prefix )
  2146. Xchar *h;
  2147. Xint rem_prefix;
  2148. X{
  2149. X    int tries;
  2150. X    register char *p1, *p2;
  2151. X    char *op1;
  2152. X
  2153. X    HZUP( h );
  2154. X    p1 = rindex(h, '.');        /* find last dot in name */
  2155. X    if( p1 != NULL ) {            /* hack for well known domains */
  2156. X    if( SCMP( p1, ".ARPA" ) ) {
  2157. X        *p1 = EOS;            /* zap it */
  2158. X        return;
  2159. X    } /* special case for .ARPA */
  2160. X    } /* got last dot */
  2161. X    else {                /* no dots at all */
  2162. X# ifdef UNPREFIX_NODOMAIN
  2163. X    if( rem_prefix )
  2164. X        unprefix( h );
  2165. X# endif /* UNPREFIX_NODOMAIN defined */
  2166. X    return;
  2167. X    } /* no dots at all */
  2168. X
  2169. X    tries = 0;
  2170. X    p1 = index(h, '.');            /* find first dot in new name */
  2171. X    if( p1 == NULL )
  2172. X    return;
  2173. X    p1++;
  2174. X    op1 = p1;
  2175. X
  2176. X# if 0
  2177. X    p2 = index( OFFICIALhostname, '.' ); /* find first dot in local name */
  2178. X    if( p2 == NULL )
  2179. X    return;
  2180. X    p2++;
  2181. X# else  /* not 0 */
  2182. X    p2 = OFFICIALhostname;        /* host may be a subdomain of ours */
  2183. X# endif /* not 0 */
  2184. X
  2185. X    for( ; ; ) {            /* loop1 */
  2186. X    for( ; ; ) {            /* loop2 */
  2187. X        tries++;
  2188. X        if( SCMP( p1, p2 ) ) {    /* both suffixes match? */
  2189. X        p1[-1] = EOS;        /* yes remove common suffix */
  2190. X        if( rem_prefix && tries == 1 ) {
  2191. X            unprefix( h );
  2192. X            return;
  2193. X        } /* removing prefixes and full domain matches */
  2194. X        } /* suffixes match */
  2195. X
  2196. X        p1 = index( p1, '.' );    /* find next dot in target string */
  2197. X        if( p1 == NULL )        /* no more? */
  2198. X        break;            /* loop2 */
  2199. X        p1++;
  2200. X    } /* loop2 */
  2201. X
  2202. X    p2 = index( p2, '.' );        /* step to next higher local domain */
  2203. X    if( p2 == NULL )
  2204. X        break;            /* loop1 */
  2205. X    p2++;
  2206. X    p1 = op1;            /* go back to first target domain */
  2207. X    } /* loop1 */
  2208. X} /* undomain */
  2209. X
  2210. XBOOL casecmp( a, b )
  2211. X    register char *a, *b;
  2212. X{
  2213. X    while( TOUP(*a) == TOUP(*b++) )
  2214. X    if( *a == EOS )
  2215. X        return( TRUE );
  2216. X    else
  2217. X        a++;
  2218. X    return( FALSE );
  2219. X} /* casecmp */
  2220. X
  2221. XGLOBAL int checkhost( host, len )
  2222. X    char *host;
  2223. X    int len;
  2224. X{
  2225. X    int o1, o2, o3, o4;
  2226. X
  2227. X    /* exactly four octets? */
  2228. X    if( isdigit( host[0] ) &&
  2229. X       sscanf( host, "%d.%d.%d.%d", &o1, &o2, &o3, &o4 ) == 4 ) {
  2230. X    char temp[ 256 ];        /* large */
  2231. X    struct in_addr in;
  2232. X    struct hostent *hp;
  2233. X
  2234. X    /* make into an address */
  2235. X    in.s_addr = (o1 << 24) | (o2 << 16) | (o3 << 8) | o4;
  2236. X
  2237. X    /* assume login was dumb. try to reverse address */
  2238. X    if( (hp = gethostbyaddr( &in, sizeof( in ), AF_INET )) != NULL ) {
  2239. X        strzcpy( host, hp->h_name, len );
  2240. X        return( TRUE );
  2241. X    }
  2242. X    else if( net_host( temp, in ) ) {
  2243. X        strzcpy( host, temp, len );
  2244. X        return( TRUE );
  2245. X    } /* getnetbyaddr */
  2246. X    } /* 4 dotted octets */
  2247. X    return( FALSE );
  2248. X} /* checkhost */
  2249. X
  2250. XGLOBAL int
  2251. Xnet_host( buf, in )
  2252. X    char *buf;
  2253. X    struct in_addr in;
  2254. X{
  2255. X    char octet[ 5 ];
  2256. X    struct netent *np;
  2257. X    long lna;
  2258. X
  2259. X    if( (np = getnetbyaddr( inet_netof( in ), AF_INET )) != NULL ) {
  2260. X    strcpy( buf, np->n_name );
  2261. X
  2262. X    lna = inet_lnaof( in );        /* get "local net address" */
  2263. X    if( lna & 0xff0000 ) {        /* 2nd octet set */
  2264. X        sprintf( octet, ".%d", (lna >> 16) & 0xff );
  2265. X        strcat( buf, octet );
  2266. X    }
  2267. X    if( lna & 0xffff00 ) {    /* 2nd or 3rd */
  2268. X        sprintf( octet, ".%d", (lna >> 8) & 0xff );
  2269. X        strcat( buf, octet );
  2270. X    }
  2271. X    sprintf( octet, ".%d", lna & 0xff ); /* Class A B and C */
  2272. X    strcat( buf, octet );
  2273. X    return( TRUE );
  2274. X    }
  2275. X    return( FALSE );
  2276. X}
  2277. X/*
  2278. X * Local variables:
  2279. X * comment-column: 40
  2280. X * End:
  2281. X */
  2282. END_OF_undomain.c
  2283. if test 5512 -ne `wc -c <undomain.c`; then
  2284.     echo shar: \"undomain.c\" unpacked with wrong size!
  2285. fi
  2286. # end of overwriting check
  2287. fi
  2288. echo shar: End of archive 3 \(of 7\).
  2289. cp /dev/null ark3isdone
  2290. MISSING=""
  2291. for I in 1 2 3 4 5 6 7 ; do
  2292.     if test ! -f ark${I}isdone ; then
  2293.     MISSING="${MISSING} ${I}"
  2294.     fi
  2295. done
  2296. if test "${MISSING}" = "" ; then
  2297.     echo You have unpacked all 7 archives.
  2298.     rm -f ark[1-9]isdone
  2299. else
  2300.     echo You still need to unpack the following archives:
  2301.     echo "        " ${MISSING}
  2302. fi
  2303. ##  End of shell archive.
  2304. exit 0
  2305.  
  2306.